package com.ljm.sys.org.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljm.common.enums.DataStatus;
import com.ljm.common.enums.ResultStatus;
import com.ljm.common.excuption.Assert;
import com.ljm.common.page.PageDto;
import com.ljm.common.util.BeanUtils;
import com.ljm.common.util.StringUtil;
import com.ljm.sys.org.api.SysOrgDepartApi;
import com.ljm.sys.org.dto.SysOrgDepartDto;
import com.ljm.sys.org.dto.SysOrgUserDto;
import com.ljm.sys.org.entity.SysOrgDepart;
import com.ljm.sys.org.mapper.SysOrgDepartMapper;
import com.ljm.sys.org.service.ISysOrgDepartService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
    * 部门表 服务实现类
    * </p>
 *
 * @author ming
 * @since 2019-04-12
 */
@Service
@Transactional
public class SysOrgDepartServiceImpl extends ServiceImpl<SysOrgDepartMapper, SysOrgDepart>
        implements ISysOrgDepartService, SysOrgDepartApi {

    private String parentIdFiel="parent_id";

    @Override
    public void saveData(SysOrgDepartDto dto, SysOrgUserDto curUser){
        SysOrgDepart po=new SysOrgDepart();
        BeanUtils.copyProperties(dto,po);
        if(StringUtil.isEmpty(dto.getId())){
            // 校验部门是否存在
            if(this.checkDept(po.getDeptName())){
                Assert.throwException(ResultStatus.FIAL.getCode(),"该部门已存在");
            }
            po.setCreateTime(LocalDateTime.now());
            po.setCreater(curUser.getLoginName());
            po.setStatus(DataStatus.NORMAL.getCode());
            po.setOrgId(curUser.getOrgId());
            po.setId(IdWorker.getId());
        }
        //配置层级信息
        if(po.getParentId()==0){
            po.setFullName("0"+"->"+po.getId());
        }else{
            //查询父
            SysOrgDepart parent=this.getById(po.getParentId());
            po.setFullName(parent.getFullName()+"->"+po.getId());
            //修改是否有child标识
            parent.setIsLeaf("0");
            this.updateById(parent);
        }
        //当前数据是否有child
        if(!StringUtil.isEmpty(po.getId())){
            if(this.countChild(po.getId())>0){//有子部门
                po.setIsLeaf("0");
            }else{
                po.setIsLeaf("1");
            }
        }
        po.setEditor(curUser.getLoginName());
        po.setEditTime(LocalDateTime.now());
        this.saveOrUpdate(po);
    }

    @Override
    public void delData(List<Long> ids){
        if(StringUtil.isEmpty(ids)){
            Assert.throwException(ResultStatus.FIAL.getCode(),"主键为空");
        }

        //处理上级是否有child问题
        for (Long id:ids){
            //检验是否有下级
            if(this.countChild(id)>0){
                Assert.throwException(ResultStatus.FIAL.getCode(),"请先删除下级部门");
            }

            SysOrgDepart po=this.getById(id);
            if(this.countChild(po.getParentId())<=1){
                //查询父级
                SysOrgDepart parent=this.getById(po.getParentId());
                parent.setIsLeaf("0");
                this.saveOrUpdate(parent);
            }
        }
        this.removeByIds(ids);
    }

    @Override
    public SysOrgDepartDto getDataById(Long id){
        if(StringUtil.isEmpty(id)){
            Assert.throwException(ResultStatus.FIAL.getCode(),"主键为空");
        }
        SysOrgDepartDto dto=new SysOrgDepartDto();
        SysOrgDepart po=this.getById(id);
        if(!StringUtil.isEmpty(po)){
            BeanUtils.copyProperties(po,dto);
        }
        return dto;
    }

    @Override
    public PageDto<SysOrgDepartDto> getDataByPage(String deptName, String type, Integer pageNo, Integer pageSize){
        PageDto<SysOrgDepartDto> pageDto=new PageDto<>(pageNo,pageSize);
        IPage<SysOrgDepart> page=new Page<>(pageNo,pageSize);
        QueryWrapper<SysOrgDepart> wrapper=new QueryWrapper<>();
        if(!StringUtil.isEmpty(deptName)){
            wrapper.like("dept_name",deptName);
        }
        if(!StringUtil.isEmpty(type)){
            wrapper.like("type",type);
        }
        wrapper.like(parentIdFiel,0);
        wrapper.orderByAsc("sort");
        page=this.page(page,wrapper);
        if(!StringUtil.isEmpty(page.getRecords())){
            pageDto.setTotal(page.getTotal());
            pageDto.setRecords(BeanUtils.copyPropertiesByList(page.getRecords(),SysOrgDepartDto.class));
        }
        return pageDto;
    }

    @Override
    public List<SysOrgDepartDto> getChildDept(Long parentId){
        List<SysOrgDepartDto> list=new ArrayList<>();
        QueryWrapper<SysOrgDepart> wrapper=new QueryWrapper<>();
        wrapper.likeRight(parentIdFiel,parentId);
        wrapper.orderByAsc("sort");
        List<SysOrgDepart> pos=this.list(wrapper);
        if(!StringUtil.isEmpty(pos)){
            list=BeanUtils.copyPropertiesByList(pos,SysOrgDepartDto.class);
        }
        return list;
    }

    @Override
    public List<SysOrgDepartDto> getAllDeptByOrgId(String orgId){
        List<SysOrgDepartDto> dtos=new ArrayList<>();
        QueryWrapper<SysOrgDepart> wrapper=new QueryWrapper<>();
        wrapper.eq("org_id",orgId);
        wrapper.orderByDesc("dept_name");
        List<SysOrgDepart> pos=this.list(wrapper);
        if(!StringUtil.isEmpty(pos)){
            dtos=BeanUtils.copyPropertiesByList(pos,SysOrgDepartDto.class);
        }
        return dtos;
    }

    @Override
    public List<SysOrgDepartDto> getRootDept(String orgId) {
        List<SysOrgDepartDto> dtos=new ArrayList<>();
        QueryWrapper<SysOrgDepart> wrapper=new QueryWrapper<>();
        wrapper.eq("org_id",orgId);
        wrapper.eq(parentIdFiel,0);
        List<SysOrgDepart> pos=this.list(wrapper);
        if(!StringUtil.isEmpty(pos)){
            dtos=BeanUtils.copyPropertiesByList(pos,SysOrgDepartDto.class);
        }
        return dtos;
    }

    private Integer countChild(Long id){
        QueryWrapper<SysOrgDepart> wrapper=new QueryWrapper<>();
        wrapper.eq(parentIdFiel,id);
        return this.count(wrapper);
    }

    /**
     * 校验部门是否存在
     * @param deptName 部门名称
     * @return 校验结果
     */
    private boolean checkDept(String deptName){
        boolean result=false;
        QueryWrapper<SysOrgDepart> wrapper=new QueryWrapper<>();
        wrapper.eq("dept_name",deptName);
        Integer count=this.count(wrapper);
        if(count>0){
            result=true;
        }
        return result;
    }
}
